package com.woniu.his.bms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.his.bms.common.BmsResultCode;
import com.woniu.his.bms.common.enums.BmsStatusEnums;
import com.woniu.his.bms.infra.model.BillsRecord;
import com.woniu.his.bms.infra.model.InvoiceRecord;
import com.woniu.his.bms.infra.model.OperatorSettleRecord;
import com.woniu.his.bms.infra.mapper.OperatorSettleRecordMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.his.bms.service.BillsRecordService;
import com.woniu.his.bms.service.InvoiceRecordService;
import com.woniu.his.bms.service.OperatorSettleRecordService;
import com.woniu.his.bms.service.dto.OperatorSettleRecordDto;
import com.woniu.his.bms.service.param.QueryOperatorSettleRecordByTimeAndStaffIdServiceParam;
import com.woniu.his.bms.service.param.VerifyForSettleRecordServiceParam;
import com.woniu.his.exception.HisException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 日结记录表 服务实现类
 * </p>
 *
 * @author chenbo
 * @since 2022-11-29
 */
@Service
public class OperatorSettleRecordServiceImpl extends ServiceImpl<OperatorSettleRecordMapper, OperatorSettleRecord> implements OperatorSettleRecordService {

    @Resource
    private InvoiceRecordService invoiceRecordService;

    @Resource
    private BillsRecordService billsRecordService;

    @Override
    public void operatorSettleRecordByTimeAndStaff(Long staffId) {

        //设置日结开始时间结束时间
        SimpleDateFormat s=new SimpleDateFormat("yyyy-MM-dd");
        DateTime startTime= DateUtil.parse(s.format(new Date()));
        Calendar calendar=new GregorianCalendar();
        calendar.setTime(startTime);
        calendar.add(Calendar.DATE, 1);
        DateTime endTime=DateUtil.parse(s.format(calendar.getTime()));

        QueryWrapper<OperatorSettleRecord> wrapper=new QueryWrapper<>();
        wrapper.eq("start_datetime",startTime);
        OperatorSettleRecord operatorSettleRecord = getOne(wrapper);
        if (operatorSettleRecord==null) {
            //第一次更新日结记录表时

            OperatorSettleRecord one = new OperatorSettleRecord();
            one.setStartDatetime(startTime);
            one.setEndDatetime(endTime);
            //创建时间
            one.setCreateDatetime(new Date());
            //收银员
            one.setCashierId(staffId);
            //设置状态
            one.setVerifyStatus(BmsStatusEnums.OFF.getCode());//状态  未核对

            //查找所有类型发票
            List<InvoiceRecord> list = invoiceRecordService.list();
            if (list.size() <= 0) return;
            //判断所有发票在当前日结条件的
            //满足时间范围内的记录
            List<InvoiceRecord> records = new ArrayList<>();
            for (InvoiceRecord invoiceRecord : list) {
                Date time = invoiceRecord.getCreateTime();


                if (time.after(startTime) && time.before(endTime)) {
                    records.add(invoiceRecord);
                }
            }
            //1.常规发票集合
            List<InvoiceRecord> normalInvoice = new ArrayList();
            //2.冲红发票集合
            List<InvoiceRecord> redInvoice = new ArrayList();
            //3.重打发票集合
            List<InvoiceRecord> repringInvoice = new ArrayList();
            for (InvoiceRecord invoiceRecord : records) {
                if (invoiceRecord.getFreezeStatus().equals(BmsStatusEnums.NORMAL.getCode())) {
                    normalInvoice.add(invoiceRecord);
                }
                if (invoiceRecord.getFreezeStatus().equals(BmsStatusEnums.RED.getCode())) {
                    redInvoice.add(invoiceRecord);
                }
                if (invoiceRecord.getFreezeStatus().equals(BmsStatusEnums.REPRING.getCode())) {
                    repringInvoice.add(invoiceRecord);
                }
            }
            //各种发票的日结数量
            one.setInvoiceNum((long) normalInvoice.size());
            one.setRushInvoiceNum((long) redInvoice.size());
            one.setReprintInvoiceNum((long) repringInvoice.size());

            //遍历满足时间范围内的账单ID
            List<Long> ids = new ArrayList<>();

            for (InvoiceRecord record : records) {
                ids.add(record.getBillId());
            }

            //查询所有账单
            List<BillsRecord> billList = billsRecordService.listByIds(ids);
            //1.所有账单中的成药ID  MEDICINE
            List<Long> medicineIds = new ArrayList();
            //2.所有账单中的草药ID  HELBAL
            List<Long> herbalIds = new ArrayList();
            //3.所有账单中的挂号ID  REGISTRATION
            List<Long> registrationIds = new ArrayList();
            //4.所有账单中的检查ID  CHECK
            List<Long> checkIds = new ArrayList();
            //5.所有账单中的检验ID  TEST
            List<Long> testIds = new ArrayList();
            //6.所有账单中的处置ID  DESPOSITION
            List<Long> despositionIds = new ArrayList();
            //所有支付的ID
            List<Long> payIds=new ArrayList<>();
            for (BillsRecord billsRecord : billList) {
                if (billsRecord.getStatus().equals(BmsStatusEnums.NOT_REGIST.getCode())||
                        billsRecord.getStatus().equals("EXCUTED")){
                    payIds.add(billsRecord.getId());
                }
                if (!billsRecord.getStatus().equals(BmsStatusEnums.DELETE)) {
                    if (billsRecord.getType().equals(BmsStatusEnums.MEDICINE.getCode())) {
                        medicineIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.HERBAL.getCode())) {
                        herbalIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.CHECK.getCode())) {
                        checkIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.TEST.getCode())) {
                        testIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.DISPOSITION.getCode())) {
                        despositionIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.REGISTRATION.getCode())) {
                        registrationIds.add(billsRecord.getId());
                    }
                }
            }
            //成药价格
            BigDecimal medicineAmount = new BigDecimal(0);
            //草药价格
            BigDecimal herbalAmount = new BigDecimal(0);
            //挂号价格
            BigDecimal registrationAmount = new BigDecimal(0);
            //检查价格
            BigDecimal checkAmount = new BigDecimal(0);
            //检验价格
            BigDecimal testAmount = new BigDecimal(0);
            //处置价格
            BigDecimal despositionAmount = new BigDecimal(0);
            //总价
            BigDecimal totalAmount = new BigDecimal(0);
            //支付宝支付的价格
            BigDecimal payAmount=new BigDecimal(0);
            for (InvoiceRecord record : records) {
                totalAmount = totalAmount.add(record.getAmount());
                for (Long payId : payIds) {
                    if (record.getBillId().equals(payId)){
                        payAmount=payAmount.add(record.getAmount());
                    }
                }
                for (Long medicineId : medicineIds) {
                    if (record.getBillId().equals(medicineId)) {
                        medicineAmount = medicineAmount.add(record.getAmount());
                    }
                }
                for (Long herbalId : herbalIds) {
                    if (record.getBillId().equals(herbalId)) {
                        herbalAmount = herbalAmount.add(record.getAmount());
                    }
                }
                for (Long re : registrationIds) {
                    if (record.getBillId().equals(re)) {
                        registrationAmount = registrationAmount.add(record.getAmount());
                    }
                }
                for (Long c : checkIds) {
                    if (record.getBillId().equals(c)) {
                        checkAmount = checkAmount.add(record.getAmount());
                    }
                }
                for (Long t : testIds) {
                    if (record.getBillId().equals(t)) {
                        testAmount = testAmount.add(record.getAmount());
                    }
                }
                for (Long d : despositionIds) {
                    if (record.getBillId().equals(d)) {
                        despositionAmount = despositionAmount.add(record.getAmount());
                    }
                }
            }
            one.setMedicineAmount(medicineAmount);
            one.setHerbalAmount(herbalAmount);
            one.setCheckAmount(checkAmount);
            one.setDispositionAmount(despositionAmount);
            one.setRegistrationAmount(registrationAmount);
            one.setTestAmount(testAmount);
            one.setAmount(totalAmount);

            one.setCashAmount(new BigDecimal(0));
            one.setInsuranceAmount(new BigDecimal(0));
            one.setBankCardAmount(new BigDecimal(0));
            one.setAlipayAmount(payAmount);
            one.setWechatAmount(new BigDecimal(0));
            one.setCreditCardAmount(new BigDecimal(0));
            one.setOtherAmount(new BigDecimal(0));
            save(one);
            //更新发票记录 关联的日结ID
            for (InvoiceRecord record : records) {
                record.setSettleRecordId(one.getId());
            }
            invoiceRecordService.updateBatchById(records);
        }else {
            //创建时间
            operatorSettleRecord.setCreateDatetime(new Date());
            //收银员
            operatorSettleRecord.setCashierId(staffId);

            //查找所有类型发票
            List<InvoiceRecord> list = invoiceRecordService.list();
            if (list.size() <= 0) return;
            //判断所有发票在当前日结条件的
            //满足时间范围内的记录
            List<InvoiceRecord> records = new ArrayList<>();
            for (InvoiceRecord invoiceRecord : list) {
                Date time = invoiceRecord.getCreateTime();
                if (time.before(startTime) && time.after(endTime)) {
                    records.add(invoiceRecord);
                }
            }
            //1.常规发票集合
            List<InvoiceRecord> normalInvoice = new ArrayList();
            //2.冲红发票集合
            List<InvoiceRecord> redInvoice = new ArrayList();
            //3.重打发票集合
            List<InvoiceRecord> repringInvoice = new ArrayList();
            for (InvoiceRecord invoiceRecord : records) {
                if (invoiceRecord.getFreezeStatus().equals(BmsStatusEnums.NORMAL.getCode())) {
                    normalInvoice.add(invoiceRecord);
                }
                if (invoiceRecord.getFreezeStatus().equals(BmsStatusEnums.RED.getCode())) {
                    redInvoice.add(invoiceRecord);
                }
                if (invoiceRecord.getFreezeStatus().equals(BmsStatusEnums.REPRING.getCode())) {
                    repringInvoice.add(invoiceRecord);
                }
            }
            //各种发票的日结数量
            operatorSettleRecord.setInvoiceNum((long) normalInvoice.size());
            operatorSettleRecord.setRushInvoiceNum((long) redInvoice.size());
            operatorSettleRecord.setReprintInvoiceNum((long) repringInvoice.size());

            //遍历满足时间范围内的账单ID
            List<Long> ids = new ArrayList<>();
            for (InvoiceRecord record : records) {
                ids.add(record.getBillId());
            }
            //查询所有账单
            List<BillsRecord> billList = billsRecordService.listByIds(ids);
            //1.所有账单中的成药ID  MEDICINE
            List<Long> medicineIds = new ArrayList();
            //2.所有账单中的草药ID  HELBAL
            List<Long> herbalIds = new ArrayList();
            //3.所有账单中的挂号ID  REGISTRATION
            List<Long> registrationIds = new ArrayList();
            //4.所有账单中的检查ID  CHECK
            List<Long> checkIds = new ArrayList();
            //5.所有账单中的检验ID  TEST
            List<Long> testIds = new ArrayList();
            //6.所有账单中的处置ID  DESPOSITION
            List<Long> despositionIds = new ArrayList();
            //所有支付的ID
            List<Long> payIds=new ArrayList<>();
            for (BillsRecord billsRecord : billList) {
                if (billsRecord.getStatus().equals(BmsStatusEnums.NOT_REGIST.getCode())||billsRecord.getStatus().equals(BmsStatusEnums.NOT_REGIST.getCode())){
                    payIds.add(billsRecord.getId());
                }
                if (!billsRecord.getStatus().equals(BmsStatusEnums.DELETE)) {
                    if (billsRecord.getType().equals(BmsStatusEnums.MEDICINE.getCode())) {
                        medicineIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.HERBAL.getCode())) {
                        herbalIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.CHECK.getCode())) {
                        checkIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.TEST.getCode())) {
                        testIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.DISPOSITION.getCode())) {
                        despositionIds.add(billsRecord.getId());
                    }
                    if (billsRecord.getType().equals(BmsStatusEnums.REGISTRATION.getCode())) {
                        registrationIds.add(billsRecord.getId());
                    }
                }
            }
            //成药价格
            BigDecimal medicineAmount = new BigDecimal(0);
            //草药价格
            BigDecimal herbalAmount = new BigDecimal(0);
            //挂号价格
            BigDecimal registrationAmount = new BigDecimal(0);
            //检查价格
            BigDecimal checkAmount = new BigDecimal(0);
            //检验价格
            BigDecimal testAmount = new BigDecimal(0);
            //处置价格
            BigDecimal despositionAmount = new BigDecimal(0);
            //总价
            BigDecimal totalAmount = new BigDecimal(0);
            //支付宝支付的价格
            BigDecimal payAmount=new BigDecimal(0);
            for (InvoiceRecord record : records) {
                totalAmount = totalAmount.add(record.getAmount());
                for (Long payId : payIds) {
                    if (record.getBillId().equals(payId)){
                        payAmount=payAmount.add(record.getAmount());
                    }
                }
                for (Long medicineId : medicineIds) {
                    if (record.getBillId().equals(medicineId)) {
                        medicineAmount = medicineAmount.add(record.getAmount());
                    }
                }
                for (Long herbalId : herbalIds) {
                    if (record.getBillId().equals(herbalId)) {
                        herbalAmount = herbalAmount.add(record.getAmount());
                    }
                }
                for (Long re : registrationIds) {
                    if (record.getBillId().equals(re)) {
                        registrationAmount = registrationAmount.add(record.getAmount());
                    }
                }
                for (Long c : checkIds) {
                    if (record.getBillId().equals(c)) {
                        checkAmount = checkAmount.add(record.getAmount());
                    }
                }
                for (Long t : testIds) {
                    if (record.getBillId().equals(t)) {
                        testAmount = testAmount.add(record.getAmount());
                    }
                }
                for (Long d : despositionIds) {
                    if (record.getBillId().equals(d)) {
                        despositionAmount = despositionAmount.add(record.getAmount());
                    }
                }
            }
            operatorSettleRecord.setMedicineAmount(medicineAmount);
            operatorSettleRecord.setHerbalAmount(herbalAmount);
            operatorSettleRecord.setCheckAmount(checkAmount);
            operatorSettleRecord.setDispositionAmount(despositionAmount);
            operatorSettleRecord.setRegistrationAmount(registrationAmount);
            operatorSettleRecord.setTestAmount(testAmount);
            operatorSettleRecord.setAmount(totalAmount);

            operatorSettleRecord.setCashAmount(new BigDecimal(0));
            operatorSettleRecord.setInsuranceAmount(new BigDecimal(0));
            operatorSettleRecord.setBankCardAmount(new BigDecimal(0));
            operatorSettleRecord.setAlipayAmount(payAmount);
            operatorSettleRecord.setWechatAmount(new BigDecimal(0));
            operatorSettleRecord.setCreditCardAmount(new BigDecimal(0));
            operatorSettleRecord.setOtherAmount(new BigDecimal(0));
            updateById(operatorSettleRecord);
            //更新发票记录 关联的日结ID
            for (InvoiceRecord record : records) {
                record.setSettleRecordId(operatorSettleRecord.getId());
            }
            invoiceRecordService.updateBatchById(records);
        }
    }

    @Override
    public OperatorSettleRecordDto queryOperatorSettleRecordById(Long id) {

        OperatorSettleRecord one = getById(id);
        if (one == null) return null;
        OperatorSettleRecordDto operatorSettleRecordDto = BeanUtil.copyProperties(one,OperatorSettleRecordDto.class);
        return operatorSettleRecordDto;
    }

    @Override
    public void verifyForSettleRecord(VerifyForSettleRecordServiceParam serviceParam) {

        OperatorSettleRecord one = getById(serviceParam.getId());
        if (one == null) throw new HisException(BmsResultCode.SETTLEMENT_RECORD_NOT_EXIST);
        one.setVerifyStatus(BmsStatusEnums.ON.getCode());//已核对
        one.setVerifyDatetime(new Date());
        one.setVerifyOperatorId(serviceParam.getVerifyOperatorId());
        updateById(one);
    }

    @Override
    public List<OperatorSettleRecordDto> queryOperatorSettleRecordByTimeAndStaffId(QueryOperatorSettleRecordByTimeAndStaffIdServiceParam serviceParam) {

        List<Long> ids=new ArrayList<>();
        if (serviceParam.getStaffId() != null&&serviceParam.getStaffId()>0){
            QueryWrapper<OperatorSettleRecord> wrapper=new QueryWrapper<>();
            wrapper.eq("cashier_id",serviceParam.getStaffId());
            List<OperatorSettleRecord> list1 = list(wrapper);
            if (list1.size()<=0) return null;
            for (OperatorSettleRecord operatorSettleRecord : list1) {
                ids.add(operatorSettleRecord.getId());
            }
        }

        //全部
        List<OperatorSettleRecord> list = list();
        List<OperatorSettleRecord> records=new ArrayList<>();

        if (serviceParam.getStartTime() != null){

            if (serviceParam.getEndTime()!= null){
                for (OperatorSettleRecord operatorSettleRecord : list) {
                    if (DateUtil.parse(serviceParam.getStartTime()).before(operatorSettleRecord.getStartDatetime())&&DateUtil.parse(serviceParam.getEndTime()).after(operatorSettleRecord.getEndDatetime())){
                        records.add(operatorSettleRecord);
                    }
                }
            }else {
                for (OperatorSettleRecord operatorSettleRecord : list) {
                    if (DateUtil.parse(serviceParam.getStartTime()).before(operatorSettleRecord.getStartDatetime())) {
                        records.add(operatorSettleRecord);
                    }
                }
            }
        }else {
            if (serviceParam.getEndTime()!= null){
                for (OperatorSettleRecord operatorSettleRecord : list) {
                    if (DateUtil.parse(serviceParam.getEndTime()).after(operatorSettleRecord.getEndDatetime())){
                        records.add(operatorSettleRecord);
                    }
                }
            }
        }
        List<OperatorSettleRecord> recordList=new ArrayList<>();
        if (records.size()<=0) return null;
        for (OperatorSettleRecord record : records) {
            for (Long id : ids) {
                if (record.getId().equals(id)){
                    recordList.add(record);
                }
            }
        }
        if (recordList.size()<= 0) return null;
        List<OperatorSettleRecordDto> operatorSettleRecordDtos = BeanUtil.copyToList(recordList, OperatorSettleRecordDto.class);
        return operatorSettleRecordDtos;
    }
}
